home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 426-450 / disk_441 / dme / src / refs.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  444 lines

  1.  
  2. /*
  3.  *  REFS.C
  4.  *
  5.  *  Bringup a cross reference editor window.  The file S:dme.refs and
  6.  *  dme.refs in the current directory are searched for the reference.
  7.  *  If found, the file specified is searched and the segment specified
  8.  *  loaded as a new file in a new window.
  9.  */
  10.  
  11. #include "defs.h"
  12. #include <libraries/dos.h>
  13.  
  14. Prototype void do_addpath (void);
  15. Prototype void do_rempath (void);
  16. Prototype void do_ctags (void);
  17. Prototype void do_refs (void);
  18. Prototype int searchref (char *, char *, char **, char **, int *, char **);
  19. Prototype int dirpart (char *);
  20.  
  21. Prototype MLIST     PBase;
  22.  
  23.  
  24. #define PEN    struct _PEN
  25.  
  26. PEN {
  27.     MNODE   Node;
  28.     char    *path;
  29. };
  30.  
  31. MLIST    PBase;        /*  special DME paths    */
  32.  
  33. /*
  34.  *  Special DME paths for REF and CTAGS
  35.  */
  36.  
  37. #ifndef NO_DO2
  38.  
  39. void
  40. do_addpath()
  41. {
  42.     PEN *pen;
  43.     short len = strlen(av[1]);
  44.  
  45.     for (pen = (PEN *)PBase.mlh_Head; pen->Node.mln_Succ; pen = (PEN *)pen->Node.mln_Succ) {
  46.     if (strcmp(av[1], pen->path) == 0)
  47.         return;
  48.     }
  49.     if (pen = malloc(sizeof(PEN)+len+2)) {
  50.     pen->path = (char *)(pen + 1);
  51.     strcpy(pen->path, av[1]);
  52.     switch(pen->path[len-1]) {
  53.     case ':':
  54.     case '/':
  55.         break;
  56.     default:
  57.         strcat(pen->path, "/");
  58.     }
  59.     }
  60.     AddTail((LIST *)&PBase, (NODE *)pen);
  61. }
  62.  
  63. void
  64. do_rempath()
  65. {
  66.     PEN *pen, *npen;
  67.  
  68.     for (pen = (PEN *)PBase.mlh_Head; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  69.     if (WildCmp(av[1], pen->path)) {
  70.         Remove((NODE *)pen);
  71.         free(pen);
  72.     }
  73.     }
  74. }
  75.  
  76. #endif
  77.  
  78. #ifndef NO_DO_CTAGS
  79.  
  80. /*
  81.  *  Implement ctags
  82.  */
  83.  
  84. void
  85. do_ctags()
  86. {
  87.     char str[64];
  88.     char path[128];
  89.     char buf[128];
  90.     char sbuf[128];
  91.     short xlen;
  92.     short slen;
  93.     short dbaselen;
  94.     BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
  95.     ED *ed;
  96.  
  97.     {
  98.     short i, j;
  99.  
  100.     for (i = Ep->Column; Current[i] == ' '; ++i);
  101.     for (j = i; ; ++j) {
  102.         short c = Current[j];
  103.         if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9'))
  104.         continue;
  105.         break;
  106.     }
  107.     j -= i;
  108.     if (j > 63)
  109.         j = 63;
  110.     movmem(Current+i, str, j);
  111.     str[j] = 0;
  112.     xlen = j;
  113.     }
  114.     if (!Ep->iconmode)
  115.     title("search tags");
  116.     {
  117.     FILE *fi;
  118.     PEN *pen, *npen;
  119.     long i;
  120.     short j, len;
  121.  
  122.     dbaselen = dirpart(Ep->Name);
  123.     movmem(Ep->Name, path, dbaselen);
  124.     strcpy(path+dbaselen, "tags");
  125.  
  126.     /*
  127.      *  Note: pen not used first pass and set to list head, so next
  128.      *  pass it will be the first element.
  129.      *
  130.      *  Note2:  The file path depends on several factors.  (1) tags in
  131.      *        'current' directory, use path to name of current window.
  132.      *        (2) tags in directory in DME special path, use special
  133.      *        path.  (3) tag entry is a full path name, override
  134.      *        previous directories.
  135.      */
  136.  
  137.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  138.         mountrequest(0);
  139.         if (fi = fopen(path, "r")) {
  140.         mountrequest(1);
  141.         while ((len = xefgets(fi, buf, 128)) >= 0) {
  142.             for (j = 0; buf[j] && buf[j] != ' '; ++j);
  143.             if (j == 0 || buf[0] == '#')
  144.             continue;
  145.             if (j == xlen && strncmp(str, buf, j) == 0) {
  146.             while (buf[j] == ' ')
  147.                 ++j;
  148.             /*
  149.              *  Extract the file name into str.  If the
  150.              *  filename does not contain an absolute path,
  151.              *  prepend it with such.
  152.              */
  153.             {
  154.                 char prep = 1;
  155.                 for (i = 0; buf[j] && buf[j] != ' '; ++i, ++j) {
  156.                 str[i] = buf[j];
  157.                 if (str[i] == ':')
  158.                     prep = 0;
  159.                 }
  160.                 if (prep) {
  161.                 movmem(str, str + dbaselen, i);
  162.                 movmem(path, str, dbaselen);
  163.                 i += dbaselen;
  164.                 }
  165.             }
  166.             str[i] = 0;
  167.  
  168.             while (buf[j] && buf[j] != '^')     /*  SEARCH ARG */
  169.                 ++j;
  170.             fclose(fi);
  171.             if (buf[j] != '^') {
  172.                 title("tags error");
  173.                 goto done;
  174.             }
  175.             ++j;
  176.             strcpy(sbuf, buf+j);
  177.             slen = strlen(sbuf);
  178.             if ((ed = finded(str, 0)) == NULL) {
  179.                 strcpy(buf, "newwindow newfile ");
  180.                 strcat(buf, str);
  181.                 do_command(buf);
  182.                 ed = finded(str, 0);
  183.             } else {
  184.                 WindowToFront(ed->Win);
  185.                 ActivateWindow(ed->Win);
  186.             }
  187.             if (ed == NULL) {
  188.                 title("unable to load file");
  189.                 goto done;
  190.             }
  191.             text_switch(ed->Win);
  192.             if (Ep->iconmode)
  193.                 uniconify();
  194.             else
  195.                 text_cursor(0);
  196.             for (i = 0; i < ed->Lines; ++i) {
  197.                 if (strncmp(ed->List[i], sbuf, slen) == 0)
  198.                 break;
  199.             }
  200.             sprintf(buf, "first goto %ld", i+1);
  201.             do_command(buf);
  202.             goto done;
  203.             }
  204.         }
  205.         fclose(fi);
  206.         } else {
  207.         mountrequest(1);
  208.         }
  209.         if (npen->Node.mln_Succ) {
  210.         strcpy(path, npen->path);
  211.         strcat(path, "tags");
  212.         dbaselen = strlen(npen->path);
  213.         }
  214.     }
  215.     title("tag not found");
  216.     }
  217. done:
  218.     CurrentDir(oldlock);
  219. }
  220.  
  221. #endif
  222.  
  223. #ifndef NO_DO_REFS
  224.  
  225. /*
  226.  *  Implement references
  227.  */
  228.  
  229. void
  230. do_refs()
  231. {
  232.     char str[256];
  233.     char path[128];
  234.     char *srch;
  235.     char *file;
  236.     char *estr;
  237.     long len;
  238.     int bcnt = 10;
  239.     short i, j;
  240.     short slen, elen;
  241.     FILE *fi, *fj;
  242.     short tmph, tmpw;
  243.     BPTR oldlock = CurrentDir((BPTR)Ep->dirlock);
  244.  
  245.     for (i = Ep->Column; Current[i] == ' '; ++i);     /*  skip spaces     */
  246.  
  247.     {
  248.     char c;
  249.  
  250.     for (j = 0; c = Current[i]; ++i, ++j) {
  251.         str[j] = c;
  252.         if (c >= 'a' && c <= 'z')
  253.         continue;
  254.         if (c >= 'A' && c <= 'Z')
  255.         continue;
  256.         if (c == '_')
  257.         continue;
  258.         break;
  259.     }
  260.     str[j] = 0;
  261.     }
  262.  
  263.     title("search .refs");
  264.  
  265.     {
  266.     PEN *pen;
  267.     PEN *npen;
  268.  
  269.     strcpy(path, "dme.refs");       /*  warning, am assuming 8 char name */
  270.     mountrequest(0);
  271.     for (pen = (PEN *)&PBase; npen = (PEN *)pen->Node.mln_Succ; pen = npen) {
  272.         if (searchref(path, str, &srch, &file, &len, &estr)) {
  273.         mountrequest(1);
  274.         goto found;
  275.         }
  276.         if (npen->Node.mln_Succ) {
  277.         strcpy(path, npen->path);
  278.         strcat(path, "dme.refs");
  279.         }
  280.     }
  281.     title("Reference not found");
  282.     mountrequest(1);
  283.     goto done;
  284.     }
  285. found:
  286.     title("search file");
  287.     slen = strlen(srch);
  288.     if (estr)
  289.     elen = strlen(estr);
  290.  
  291.     fi = fopen(file, "r");
  292.     if (fi == NULL) {       /*  try using path prefix   */
  293.     strcpy(str, path);
  294.     strcpy(str + strlen(str) - 8, file);
  295.     fi = fopen(str, "r");
  296.     }
  297.     if (fi) {
  298.     short lenstr;
  299.     if (srch[0] == '@' && srch[1] == '@') {
  300.         fseek(fi, atoi(srch+2), 0);
  301.         if ((lenstr = xefgets(fi, str, 256)) >= 0)
  302.         goto autoseek;
  303.     }
  304.     while ((lenstr = xefgets(fi, str, 256)) >= 0) {
  305.         if (strncmp(str, srch, slen) == 0) {
  306. autoseek:
  307.         title("load..");
  308.         if (fj = fopen("t:dme_ref", "w")) {
  309.             tmph = 0;
  310.             tmpw = 0;
  311.             do {
  312.             if (lenstr > tmpw)
  313.                 tmpw = strlen(str);
  314.             ++tmph;
  315.             fputs(str, fj);
  316.             fputc('\n', fj);
  317.             if (estr && strncmp(str,estr,elen) == 0)
  318.                 break;
  319.             --len;
  320.             } while ((lenstr=xefgets(fi, str, 256)) >= 0 && len);
  321.             fclose(fj);
  322.             if (tmph > 10)
  323.             tmph = 10;
  324.             if (tmpw > 80)
  325.             tmpw = 80;
  326.             sprintf(str, "openwindow +0+0+%d+%d newfile t:dme_ref", (tmpw<<3)+24, (tmph<<3)+24);
  327.             do_command(str);
  328.             unlink("t:dme_ref");
  329.         } else {
  330.             title("Unable to open t:dme_ref for write");
  331.         }
  332.         fclose(fi);
  333.         free(srch);
  334.         free(file);
  335.         if (estr)
  336.             free(estr);
  337.         goto done;
  338.         }
  339.         if (--bcnt == 0) {      /* check break every so so  */
  340.         bcnt = 50;
  341.         if (breakcheck())
  342.             break;
  343.         }
  344.     }
  345.     fclose(fi);
  346.     title("Search failed");
  347.     } else {
  348.     title("Unable to open sub document");
  349.     }
  350.     free(srch);
  351.     free(file);
  352.     if (estr)
  353.     free(estr);
  354. done:
  355.     CurrentDir(oldlock);
  356. }
  357.  
  358. /*
  359.  *  Reference file format:
  360.  *
  361.  *  `key' `lines' `file' `searchstring'
  362.  *
  363.  *  where `lines' can be a string instead ... like a read-until, otherwise
  364.  *  the number of lines to read from the reference.
  365.  */
  366.  
  367. searchref(file, find, psstr, pfile, plines, pestr)
  368. char *file, *find;
  369. char **psstr, **pfile, **pestr;
  370. long *plines;
  371. {
  372.     FILE *fi;
  373.     char buf[256];
  374.     char *ptr, *base;
  375.     char *b1, *b2, *b3, *b4;
  376.     char quoted;
  377.     short findlen = strlen(find);
  378.  
  379.     if (fi = fopen(file, "r")) {
  380.     while (xefgets(fi, (base=buf), 256) >= 0) {
  381.         if (buf[0]=='#')
  382.         continue;
  383.         ptr = breakout(&base, "ed, &b1);
  384. /*          if (ptr && *ptr && strncmp(ptr, find, findlen) == 0) { */
  385.         if (ptr && *ptr && strcmp(ptr, find) == 0) {
  386.         if (ptr = breakout(&base, "ed, &b2)) {
  387.             *pestr = NULL;
  388.             *plines = atoi(ptr);
  389.             if (*plines == 0) {
  390.             *pestr = (char *)malloc(strlen(ptr)+1);
  391.             strcpy(*pestr, ptr);
  392.             }
  393.             if (ptr = breakout(&base, "ed, &b3)) {
  394.             *pfile = (char *)malloc(strlen(ptr)+1);
  395.             strcpy(*pfile, ptr);
  396.             if (ptr = breakout(&base, "ed, &b4)) {
  397.                 *psstr = (char *)malloc(strlen(ptr)+1);
  398.                 strcpy(*psstr, ptr);
  399.                 fclose(fi);
  400.                 if (b1) free(b1);
  401.                 if (b2) free(b2);
  402.                 if (b3) free(b3);
  403.                 if (b4) free(b4);
  404.                 return(1);
  405.             }
  406.             free(*pfile);
  407.             if (b4)
  408.                 free(b4);
  409.             }
  410.             if (pestr)
  411.             free (*pestr);
  412.             if (b3)
  413.             free (b3);
  414.         }
  415.         if (b2)
  416.             free(b2);
  417.         }
  418.         if (b1)
  419.         free(b1);
  420.     }
  421.     fclose(fi);
  422.     }
  423.     return(0);
  424. }
  425.  
  426. #endif
  427.  
  428. #ifndef NO_DO_CTAGS
  429.  
  430. dirpart(str)
  431. char *str;
  432. {
  433.     short i;
  434.  
  435.     for (i = strlen(str) - 1; i >= 0; --i) {
  436.     if (str[i] == '/' || str[i] == ':')
  437.         break;
  438.     }
  439.     return(i+1);
  440. }
  441.  
  442. #endif
  443.  
  444.